package com.qfedu.edu.config;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;

/**
 * @author xiaobobo
 * @title: RabbitMQConfig
 * @projectName cd-fy-2401-third-project-parent
 * @description: 这个是咋们的RabbitMQ的配置文件
 * @date 2024/10/9  16:41
 */
@SpringBootConfiguration
@ConditionalOnProperty(name = "framework.config.mq", havingValue = "true")
public class RabbitMQConfig {

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        //设置rabbitTemplate支持事务
        rabbitTemplate.setChannelTransacted(true);
        return rabbitTemplate;
    }


    @Bean
    public Queue emqxQueue(){
        return new Queue("emqxQueue",true,false,false);
    }

    //所以要解决 消费成功业务执行失败的问题
    /**
     * 这个是咋们的异常交换机
     * @return
     */
    @Bean
    public FanoutExchange fanoutExceptionExchange(){
        return new FanoutExchange("fanoutExceptionExchange");
    }

    @Bean
    public Queue exceptionQueue(){
       return new Queue("exceptionQueue",true,false,false);
    }

    //将异常队列 绑定到 异常交换机
    @Bean
    public Binding binding1(Queue exceptionQueue,FanoutExchange fanoutExceptionExchange){
        return BindingBuilder.bind(exceptionQueue).to(fanoutExceptionExchange);
    }

    //接下来就是重试策略
    //接下来就是重试多次之后依然失败的处理方式(第一种处理方式)
    @Bean
    public MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate){
        return new RepublishMessageRecoverer(rabbitTemplate,"fanoutExceptionExchange","");
    }

    //申明一个通道
    /**
     * 申明这个通道的目的是为了找到队列中的消费者的个数 以及消息的个数
     * @param connectionFactory
     * @return
     */
    @Bean
    public Channel channel(ConnectionFactory connectionFactory){
        return connectionFactory.createConnection().createChannel(true);
    }

}
